package com.xuelang.pipeline.artifact.infrastructure.resource.repository;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.xuelang.pipeline.artifact.client.common.constant.Constant;
import com.xuelang.pipeline.artifact.client.common.result.PageRecord;
import com.xuelang.pipeline.artifact.client.common.util.MavenUtil;
import com.xuelang.pipeline.artifact.client.resource.dto.RepositoryComponentQuery;
import com.xuelang.pipeline.artifact.domain.resource.RepositoryComponent;
import com.xuelang.pipeline.artifact.domain.resource.repository.RepositoryComponentRepository;
import com.xuelang.pipeline.artifact.infrastructure.resource.converter.RepositoryComponentToRepositoryComponentDOConverter;
import com.xuelang.pipeline.artifact.infrastructure.resource.dataobject.ArtifactAttributeDO;
import com.xuelang.pipeline.artifact.infrastructure.resource.dataobject.RepositoryComponentDO;
import com.xuelang.pipeline.artifact.infrastructure.resource.mapper.RepositoryComponentMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * 仓库制品组件仓库实现类
 *
 * @author xiwen.zxg
 * @since 2024/5/15
 */
@Slf4j
@Repository
public class RepositoryComponentRepositoryImpl implements RepositoryComponentRepository {

    @Autowired
    RepositoryComponentMapper repositoryComponentMapper;

    @Override
    public PageRecord<RepositoryComponent> pageList(long currentPage, long pageSize, RepositoryComponentQuery repositoryComponentQuery) {
        currentPage = currentPage < 1 ? 1 : currentPage;
        pageSize = pageSize < 1 ? 10 : pageSize;
        Page<RepositoryComponent> page = new Page<>(currentPage, pageSize);
        MPJLambdaWrapper<RepositoryComponentDO> wrapper = new MPJLambdaWrapper<RepositoryComponentDO>();
        wrapper.selectAll(RepositoryComponentDO.class)
                //.eq(RepositoryComponentDO::getFormat, StrUtil.isNotBlank(repositoryComponentQuery.getFormat()) ? repositoryComponentQuery.getFormat() : Constant.DEFAULT_DB_NOT_EXISTS_DATA)
                .eq(RepositoryComponentDO::getPackageUuid, StrUtil.isNotBlank(repositoryComponentQuery.getPackageUuid()) ? repositoryComponentQuery.getPackageUuid() : Constant.DEFAULT_DB_NOT_EXISTS_DATA);
        wrapper.and(StrUtil.isNotBlank(repositoryComponentQuery.getCondition()), wp -> wp
                        .like(RepositoryComponentDO::getNameId, repositoryComponentQuery.getCondition()).or()
                        .like(RepositoryComponentDO::getGroupId, repositoryComponentQuery.getCondition()).or()
                        .like(RepositoryComponentDO::getRestId, repositoryComponentQuery.getCondition()).or()
                        .like(RepositoryComponentDO::getScriptId, repositoryComponentQuery.getCondition()))
                .apply(StrUtil.isNotBlank(repositoryComponentQuery.getStartDate()), "DATE_FORMAT(t.create_time,'%Y-%m-%d')>={0}", repositoryComponentQuery.getStartDate())
                .apply(StrUtil.isNotBlank(repositoryComponentQuery.getStartDate()), "DATE_FORMAT(t.create_time,'%Y-%m-%d')<={0}", repositoryComponentQuery.getEndDate())
                .orderByDesc(ArtifactAttributeDO::getCreateTime);
        repositoryComponentMapper.selectJoinPage(page, RepositoryComponent.class, wrapper);
        return new PageRecord<>(
                page.getCurrent(),
                page.getSize(),
                page.getTotal(),
                page.getPages(),
                page.getRecords()
        );
    }

    @Override
    public List<RepositoryComponent> list(RepositoryComponentQuery repositoryComponentQuery) {
        MPJLambdaWrapper<RepositoryComponentDO> wrapper = new MPJLambdaWrapper<RepositoryComponentDO>();
        wrapper.selectAll(RepositoryComponentDO.class)
                //.eq(RepositoryComponentDO::getFormat, StrUtil.isNotBlank(repositoryComponentQuery.getFormat()) ? repositoryComponentQuery.getFormat() : Constant.DEFAULT_DB_NOT_EXISTS_DATA)
                .eq(RepositoryComponentDO::getPackageUuid, StrUtil.isNotBlank(repositoryComponentQuery.getPackageUuid()) ? repositoryComponentQuery.getPackageUuid() : Constant.DEFAULT_DB_NOT_EXISTS_DATA);
        wrapper.and(StrUtil.isNotBlank(repositoryComponentQuery.getCondition()), wp -> wp
                        .like(RepositoryComponentDO::getNameId, repositoryComponentQuery.getCondition()).or()
                        .like(RepositoryComponentDO::getGroupId, repositoryComponentQuery.getCondition()).or()
                        .like(RepositoryComponentDO::getRestId, repositoryComponentQuery.getCondition()).or()
                        .like(RepositoryComponentDO::getScriptId, repositoryComponentQuery.getCondition()))
                .apply(StrUtil.isNotBlank(repositoryComponentQuery.getStartDate()), "DATE_FORMAT(t.create_time,'%Y-%m-%d')>={0}", repositoryComponentQuery.getStartDate())
                .apply(StrUtil.isNotBlank(repositoryComponentQuery.getStartDate()), "DATE_FORMAT(t.create_time,'%Y-%m-%d')<={0}", repositoryComponentQuery.getEndDate())
                .orderByDesc(ArtifactAttributeDO::getCreateTime);
        return repositoryComponentMapper.selectJoinList(RepositoryComponent.class, wrapper);
    }


    @Override
    public Boolean save(RepositoryComponent repositoryComponent) {
        return repositoryComponentMapper.insert(RepositoryComponentToRepositoryComponentDOConverter.INSTANCE.repositoryComponentToRepositoryComponentDO(repositoryComponent)) == 1;
    }

    @Override
    public Boolean update(RepositoryComponent repositoryComponent) {
        return repositoryComponentMapper.update(
                RepositoryComponentToRepositoryComponentDOConverter.INSTANCE.repositoryComponentToRepositoryComponentDO(repositoryComponent),
                Wrappers.lambdaQuery(RepositoryComponentDO.class).eq(RepositoryComponentDO::getRestId, repositoryComponent.getRestId())) == 1;
    }

    @Override
    public Boolean delete(String restId) {
        return repositoryComponentMapper.delete(Wrappers.lambdaQuery(RepositoryComponentDO.class)
                .eq(RepositoryComponentDO::getRestId, restId)) == 1;
    }

    @Override
    public RepositoryComponent query(String restId) {
        RepositoryComponentDO repositoryComponentDO = repositoryComponentMapper.selectOne(Wrappers.lambdaQuery(RepositoryComponentDO.class).eq(RepositoryComponentDO::getRestId, restId));
        return RepositoryComponentToRepositoryComponentDOConverter.INSTANCE.repositoryComponentDOToRepositoryComponent(repositoryComponentDO);
    }

    @Override
    public List<RepositoryComponent> listByPackage(String instanceRepositoryName, String name, String group, String format) {
        MPJLambdaWrapper<RepositoryComponentDO> wrapper = new MPJLambdaWrapper<>();
        wrapper.eq(StrUtil.isNotBlank(instanceRepositoryName), RepositoryComponentDO::getInstanceRepositoryName, instanceRepositoryName);
        wrapper.eq(StrUtil.isNotBlank(name), RepositoryComponentDO::getNameId, name);
        wrapper.eq(StrUtil.isNotBlank(group), RepositoryComponentDO::getGroupId, group);
        wrapper.eq(StrUtil.isNotBlank(format), RepositoryComponentDO::getFormat, format);
        wrapper.eq(StrUtil.isNotBlank(MavenUtil.joinGroupAndName(group, name)), RepositoryComponentDO::getPackageName, MavenUtil.joinGroupAndName(group, name));
        wrapper.orderByDesc(RepositoryComponentDO::getCreateTime);
        return repositoryComponentMapper.selectJoinList(RepositoryComponent.class, wrapper);
    }

    @Override
    public void updateComponentsToOldVersion(String packageUuid) {
        repositoryComponentMapper.update(RepositoryComponentDO.builder().isLatest(false).build(),
                Wrappers.lambdaUpdate(RepositoryComponentDO.class).eq(RepositoryComponentDO::getPackageUuid, packageUuid));
    }

    @Override
    public RepositoryComponent queryContainsDigestAndPushVersion(String instanceRepositoryName, String packageName, String currentDigest, String currentPushVersion, String format) {
        MPJLambdaWrapper<RepositoryComponentDO> wrapper = new MPJLambdaWrapper<>();
        wrapper.eq(StrUtil.isNotBlank(instanceRepositoryName), RepositoryComponentDO::getInstanceRepositoryName, instanceRepositoryName);
        wrapper.eq(StrUtil.isNotBlank(packageName), RepositoryComponentDO::getPackageName, packageName);
        wrapper.eq(StrUtil.isNotBlank(currentPushVersion), RepositoryComponentDO::getVersion, currentPushVersion);
        wrapper.eq(StrUtil.isNotBlank(format), RepositoryComponentDO::getFormat, format);
        wrapper.like(StrUtil.isNotBlank(currentDigest), RepositoryComponentDO::getScriptId, currentDigest);
        wrapper.orderByDesc(RepositoryComponentDO::getCreateTime);
        return repositoryComponentMapper.selectJoinOne(RepositoryComponent.class, wrapper);
    }

    @Override
    public List<RepositoryComponent> listByPackageName(String instanceRepositoryName, String packageName, String format) {
        MPJLambdaWrapper<RepositoryComponentDO> wrapper = new MPJLambdaWrapper<>();
        wrapper.eq(StrUtil.isNotBlank(instanceRepositoryName), RepositoryComponentDO::getInstanceRepositoryName, instanceRepositoryName);
        wrapper.eq(StrUtil.isNotBlank(packageName), RepositoryComponentDO::getPackageName, packageName);
        wrapper.eq(StrUtil.isNotBlank(format), RepositoryComponentDO::getFormat, format);
        wrapper.orderByDesc(RepositoryComponentDO::getCreateTime);
        return repositoryComponentMapper.selectJoinList(RepositoryComponent.class, wrapper);
    }

    @Override
    public Boolean deleteByPackageUuid(String packageUuid) {
        return repositoryComponentMapper.delete(
                Wrappers.lambdaQuery(RepositoryComponentDO.class)
                        .eq(RepositoryComponentDO::getPackageUuid, packageUuid)) > 0;
    }

}
